﻿using System;
using System.Collections.Generic;
using smp.ButterflyCakes.Domain.Interfaces;
using smp.ButterflyCakes.Models;
using smp.ButterflyCakes.Models.Data;
using smp.ButterflyCakes.Models.FormModels.Order;
using smp.ButterflyCakes.Repository.Implementation;
using smp.ButterflyCakes.Repository.Interfaces;

namespace smp.ButterflyCakes.Domain.Implementation
{
    public class Order : IOrder
    {
        #region members and constructors

        private readonly IDomainOrderRepository _repository;
        private readonly NextOrderStage _currentLastStage;
        private DomainResponse _response;
        private readonly bool _loadSuccess;
        private readonly Guid _id;
        private readonly List<StageDataItem> _stages;
        
        public Order()
            : this(new DomainOrderRepository())
        {
        }

        public Order(IDomainOrderRepository repository)
        {
            _repository = repository;
        }

        public Order(Guid id)
            : this(id, new DomainOrderRepository())
        {
        }

        public Order(Guid id, IDomainOrderRepository repository)
        {
            _repository = repository;
            var data = _repository.GetOrderData(id);
            if(data == null || data.LastStage == null)
            {
                _loadSuccess = false;
                _response = new DomainResponse("Failed to load order for Id : " + id);
                return;
            }
            _currentLastStage = data.LastStage;
            _id = id;
            _stages = data.Stages;
            _loadSuccess = true;
        }

        #endregion

        #region Implementation of IOrder

        public DomainResponse Create(Guid id)
        {
            var componentId = Guid.NewGuid();
            var stage = new StageDataItem(id, componentId, Stage.OrderSummary, 0);
            var result = _repository.CreateOrder(id, componentId, stage);
            return result ? new DomainResponse(Stage.OrderSummary) : new DomainResponse("Failed to create new order");
        }   

        public DomainResponse SetSummary(OrderSummaryModel model)
        {
            if (!_loadSuccess)
                return _response;
            StageDataItem stage = null;
            if(_currentLastStage.Stage == Stage.OrderSummary)
            {
                stage = new StageDataItem(model.ComponentId, Stage.ContactInformation, _currentLastStage);
                _response = new DomainResponse(stage.Stage);
            }
            else
            {
                _response = new DomainResponse(_currentLastStage.Stage);
            }

            if(!_repository.SaveOrderSummary(model, stage))
                return new DomainResponse("Failed to save order summary and create next stage");

            return _response;
        }

        public DomainResponse SetContact(ContactInformationModel model)
        {
            if(!_loadSuccess)
                return _response;
            if(!_repository.SaveContactInformation(model))
            {
                return new DomainResponse("Failed to save contact information");
            }

            return _currentLastStage.Stage == Stage.ContactInformation
                       ? new DomainResponse(true, _currentLastStage.Stage)
                       : new DomainResponse(_currentLastStage.Stage);
        }

        public DomainResponse AddCake(Guid id)
        {
            if (!_loadSuccess)
                return _response;
            var firstStage = new StageDataItem(id, Stage.ComponentTitle, _currentLastStage);
            if(!_repository.CreateCake(_id, id, firstStage))
            {
                return new DomainResponse("Failed to create cake");
            }
            return new DomainResponse(firstStage.Stage);
        }

        #endregion
    }
}
